小编在做 iOS 开发过程中有时会遇到想要对现有的类添加新的方法,或者是覆盖替换原来方法情况。也在有的情况我们在类实现过程中想要隐藏一些方法和属性情况。
所以就对实现一些注意做下整理:
Category : 运行期决议
- 可以把类实现分在不同类中实现。这样做有几个优点:1)可以减少单个类的体积 2)可以把不同的功能放在不同的
Category
进行实现 3)可以多人同时开发一个类 4)可以更具具体的需要实现Category
加载等 - 可以添加私有方法
Extension : 编译器决议
- 可以添加不想要暴露的类私有方法
- 可以添加类属性和类实例变量
Category 和 Extension 对比
Category
和 Extension
区别
Category(类目)和Extension(类拓展)有很大的区别。
Category
在运行期决定,不能对其进行添加实例变量(因为在编译器已经决定当前内存结构,如果可以添加实例变量就会造成当前类布局改变)。但是可以对现有的类进行添加类目。SDWebImage
中就有大量的使用。Extension
可以看作是没有名字的 Category
,但是两者还是由本质的区别。Extension
是在编译器就已经决定的,而且和 interface
、 implement
共同组成类的一部分,三者同时在编译器决定并且一起消亡。所以对 iOS
中已经存在的实现类不能进行添加 Estension
的拓展。注:主要作用是隐藏类的一些相关信息。参考
Category
和 Extension
具体实现
1)Category
的实现
下面是对 NSString
添加类目,下面以 NSString+Configuration
类目展示:
NSString+Configuration.h
1 |
|
NSString+Configuration.m
实现文件
1 |
|
2)Extension
的具体实现,下面以 Person
类:
Person.h
文件
1 |
|
Person.m
文件
1 | @interface Person () |
Category 真面目
如果对 runtime
有所了解,可以知道 OC 的很多是在 struct
的基础上完成的。 Category_t
在 struct
的结构上如下(在objc_runtime_new.h
中):
1 | struct category_t { |
由上面可以看出:
Category
里面可以添加实例方法、类方法、协议和类属性。
注释:
在
Category
中添加的方法会放在原来类方法的前面,在调用方法过程中会调用前面方法,就会形成被类被覆盖
的现象。原因是在调用类的过程中寻找调用方法是从上到下类进行查找的。
调用 Category
覆盖的方法
在 Category
覆盖的方法,是在查找过程中由于调用前面的方法而造成相关方法的覆盖。我们可以在调用前把 Category
的方法跳过。
具体实现如下:
1 | Class currentClass = [Person class]; |
Category
添加关联对象
Category
中不能添加类的变量。但我们通常需要添加关联对象的值,可以实现关联对象来进行实现。
Person+Habit.h
文件:
1 | @interface Person (Habit) |
Person+Habit.m
文件:
1 |
|
参考资料:
runtime
Category
Customizing Existing Classes
深入理解Objective-C
深入浅出理解分类(category)和类扩展(extension)